#!/usr/bin/env python3
"""
C语言语法高亮器
支持C语言的关键字、数据类型、预处理器指令、注释、字符串、数字等语法元素的高亮
"""

from PyQt5.QtCore import QRegExp
from PyQt5.QtGui import QSyntaxHighlighter, QTextCharFormat, QFont, QColor

class CHighlighter(QSyntaxHighlighter):
    def __init__(self, parent=None):
        super(CHighlighter, self).__init__(parent)
        self.highlighting_rules = []
        
        # 关键字格式 - 蓝色加粗
        keyword_format = QTextCharFormat()
        keyword_format.setForeground(QColor(255,85,0))  #
        keyword_format.setFontWeight(QFont.Bold)
        
        # C语言关键字
        keywords = [
            'auto', 'break', 'case', 'char', 'const', 'continue', 'default', 'do',
            'double', 'else', 'enum', 'extern', 'float', 'for', 'goto', 'if',
            'int', 'long', 'register', 'return', 'short', 'signed', 'sizeof', 'static',
            'struct', 'switch', 'typedef', 'union', 'unsigned', 'void', 'volatile', 'while'
        ]
        
        # 为每个关键字创建规则
        for keyword in keywords:
            pattern = QRegExp(r'\b' + keyword + r'\b')
            self.highlighting_rules.append((pattern, keyword_format))
        
        # 数据类型格式 - 深蓝色
        type_format = QTextCharFormat()
        type_format.setForeground(QColor(255,170,0))  # 紫色
        type_format.setFontWeight(QFont.Bold)
        
        # 数据类型
        data_types = ['bool', 'size_t', 'ssize_t', 'int8_t', 'int16_t', 'int32_t', 'int64_t',
                     'uint8_t', 'uint16_t', 'uint32_t', 'uint64_t', 'intptr_t', 'uintptr_t']
        
        for data_type in data_types:
            pattern = QRegExp(r'\b' + data_type + r'\b')
            self.highlighting_rules.append((pattern, type_format))
        
        # 预处理器指令格式 - 紫色
        preprocessor_format = QTextCharFormat()
        preprocessor_format.setForeground(QColor(128, 0, 128))  # 紫色
        preprocessor_format.setFontWeight(QFont.Bold)
        
        preprocessor_directives = [
            '#include', '#define', '#undef', '#if', '#ifdef', '#ifndef', '#else',
            '#elif', '#endif', '#error', '#pragma', '#line'
        ]
        
        for directive in preprocessor_directives:
            pattern = QRegExp(directive.replace('#', r'\s*#') + r'\b')
            self.highlighting_rules.append((pattern, preprocessor_format))
        
        # 宏定义格式 - 深紫色
        macro_format = QTextCharFormat()
        macro_format.setForeground(QColor(75, 0, 130))  # 深紫色
        
        # 宏定义模式
        macro_pattern = QRegExp(r'\b[A-Z_][A-Z0-9_]*\b')
        self.highlighting_rules.append((macro_pattern, macro_format))
        
        # 单行注释格式 - 灰色
        single_line_comment_format = QTextCharFormat()
        single_line_comment_format.setForeground(QColor(128, 128, 128))  # 灰色
        
        single_line_comment_pattern = QRegExp(r'//[^\n]*')
        self.highlighting_rules.append((single_line_comment_pattern, single_line_comment_format))
        
        # 多行注释格式 - 灰色
        self.multi_line_comment_format = QTextCharFormat()
        self.multi_line_comment_format.setForeground(QColor(128, 128, 128))  # 灰色
        
        # 字符串格式 - 绿色
        string_format = QTextCharFormat()
        string_format.setForeground(QColor(0, 128, 0))  # 绿色
        
        # 字符串模式
        string_pattern = QRegExp(r'"[^"\\]*(\\.[^"\\]*)*"')
        self.highlighting_rules.append((string_pattern, string_format))
        
        # 字符格式 - 深绿色
        char_format = QTextCharFormat()
        char_format.setForeground(QColor(0, 100, 0))  # 深绿色
        
        # 字符模式
        char_pattern = QRegExp(r"'[^'\\]*(\\.[^'\\]*)*'")
        self.highlighting_rules.append((char_pattern, char_format))
        
        # 数字格式 - 橙色
        number_format = QTextCharFormat()
        number_format.setForeground(QColor(255, 140, 0))  # 橙色
        
        # 数字模式（整数、浮点数、十六进制、八进制）
        number_pattern = QRegExp(r'\b\d+(\.\d+)?([eE][+-]?\d+)?\b|\b0[xX][0-9a-fA-F]+\b|\b0[0-7]+\b')
        self.highlighting_rules.append((number_pattern, number_format))
        
        # 函数调用格式 - 深蓝色
        function_format = QTextCharFormat()
        function_format.setForeground(QColor(0, 0, 255))  # 蓝色
        
        # 函数调用模式
        function_pattern = QRegExp(r'\b[A-Za-z_][A-Za-z0-9_]*(?=\s*\()')
        self.highlighting_rules.append((function_pattern, function_format))
        
        # 运算符格式 - 红色
        operator_format = QTextCharFormat()
        operator_format.setForeground(QColor(255, 0, 0))  # 红色
        operator_format.setFontWeight(QFont.Bold)
        
        # 运算符模式
        operators = ['+', '-', '*', '/', '%', '=', '==', '!=', '<', '>', '<=', '>=', 
                    '&&', '||', '!', '&', '|', '^', '~', '<<', '>>', '++', '--',
                    '+=', '-=', '*=', '/=', '%=', '&=', '|=', '^=', '<<=', '>>=']
        
        for operator in operators:
            # 转义特殊字符
            escaped_operator = QRegExp.escape(operator)
            pattern = QRegExp(escaped_operator)
            self.highlighting_rules.append((pattern, operator_format))
        
        # 多行注释的开始和结束模式
        self.comment_start_expression = QRegExp(r'/\*')
        self.comment_end_expression = QRegExp(r'\*/')
    
    def highlightBlock(self, text):
        """高亮文本块"""
        # 应用所有高亮规则
        for pattern, format in self.highlighting_rules:
            expression = QRegExp(pattern)
            index = expression.indexIn(text)
            while index >= 0:
                length = expression.matchedLength()
                self.setFormat(index, length, format)
                index = expression.indexIn(text, index + length)
        
        # 处理多行注释
        self.setCurrentBlockState(0)
        
        start_index = 0
        if self.previousBlockState() != 1:
            start_index = self.comment_start_expression.indexIn(text)
        
        while start_index >= 0:
            end_index = self.comment_end_expression.indexIn(text, start_index)
            
            if end_index == -1:
                self.setCurrentBlockState(1)
                comment_length = len(text) - start_index
                self.setFormat(start_index, comment_length, self.multi_line_comment_format)
                break
            else:
                comment_length = end_index - start_index + self.comment_end_expression.matchedLength()
                self.setFormat(start_index, comment_length, self.multi_line_comment_format)
                start_index = self.comment_start_expression.indexIn(text, start_index + comment_length)

    def get_highlighting_rules_count(self):
        """获取高亮规则数量"""
        return len(self.highlighting_rules)